//
//  MGRequestService.m
//  MortgageHelper
//
//  Created by zhangxiang on 16/8/8.
//  Copyright © 2016年 zhangxiang. All rights reserved.
//
#import "MGRequestService.h"
#import "RealReachability.h"
#import "SecurityUtil.h"
#define KEY @"anjiebang2017329" //key可修改
# define isProduction  1


@interface MGRequestService ()

@property (nonatomic, strong) MGUserInfoModel * userInfo;
@property (nonatomic, strong) AFHTTPSessionManager *manager;

@end

@implementation MGRequestService

+ (MGRequestService *)sharedAPI{
    static MGRequestService *_sharedRequestAPI = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedRequestAPI = [[MGRequestService alloc] init];
        [GLobalRealReachability startNotifier];
        
    });
    
    return _sharedRequestAPI;
}
- (void)networkChanged:(NSNotification *)notification
{
    RealReachability *reachability = (RealReachability *)notification.object;
    ReachabilityStatus status = [reachability currentReachabilityStatus];
    NSLog(@"currentStatus:%@",@(status));
}


+(void)configeWithuserInfo:(MGUserInfoModel *)userInfo {
    NSString *baseURLString=nil;
    if (isProduction) {
       baseURLString=@"https://api.beerich.cn:4430";
    }else{
       baseURLString=@"https://bs.anjiebang.com:4430";
    }
    // 设置超时等待的时间
    MGRequestService *requestService = [MGRequestService sharedAPI];
    
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    requestService.manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:baseURLString]
                                                      sessionConfiguration:configuration];
    requestService.userInfo = userInfo;
    //包括初始化
    requestService.manager.requestSerializer.timeoutInterval = 15.0;
    
    // 配置请求头信息
    [requestService configureHTTPHeaderField];
    
    // 设置客户端可接受内容的类型

    NSMutableSet *acceptableContentTypes = [NSMutableSet setWithSet:requestService.manager.responseSerializer.acceptableContentTypes];
    [acceptableContentTypes addObject:@"text/plain"];
    [acceptableContentTypes addObject:@"text/html"];
    //    [acceptableContentTypes addObject:@"multipart/form-data"];
    requestService.manager.responseSerializer.acceptableContentTypes = acceptableContentTypes;
    
    [[NSNotificationCenter defaultCenter] addObserver:RequestService
                                             selector:@selector(networkChanged:)
                                                 name:kRealReachabilityChangedNotification
                                               object:nil];
}
-(id)obtainDeviceID{
    
    NSString * const KEY_USERNAME_PASSWORD = @"com.lzy.anjiebang.usernamepassword";
    NSString * const KEY_PASSWORD = @"com.lzy.anjiebang.password";
    NSMutableDictionary *readUserPwd = (NSMutableDictionary *)[self loadKeyChainValueWithKey:KEY_USERNAME_PASSWORD];
    if([readUserPwd isKindOfClass:[NSDictionary class]]){
        return readUserPwd[KEY_PASSWORD];
    }else{
        NSString *identifierStr = @"";
//        if(UserInfoManage.userInfo.userId){
//            identifierStr = [NSString stringWithFormat:@"%@", UserInfoManage.userInfo.userId];
//        }else{
            identifierStr = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
//        }
        NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary];
        [usernamepasswordKVPairs setObject:identifierStr forKey:KEY_PASSWORD];
        
        //存
        [self save:KEY_USERNAME_PASSWORD data:usernamepasswordKVPairs];
        return identifierStr;
    }
}
- (void)save:(NSString *)service data:(id)data{
    //Get search dictionary
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Delete old item before add new item
    SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
    //Add new object to search dictionary(Attention:the data format)
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
    //Add item to keychain with the search dictionary
    SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
}
-(NSMutableDictionary *)getKeychainQuery:(NSString *)service{
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (__bridge id)kSecClassGenericPassword,(__bridge id)kSecClass,
            service, (__bridge id)kSecAttrService,
            service, (__bridge id)kSecAttrAccount,
            (__bridge id)kSecAttrAccessibleAfterFirstUnlock,(__bridge id)kSecAttrAccessible,
            nil];
}
-(id)loadKeyChainValueWithKey:(NSString *)service{
    
    id ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Configure the search setting
    //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
    [keychainQuery setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
    [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
        } @catch (NSException *e) {
            NSLog(@"Unarchive of %@ failed: %@", service, e);
        } @finally {
        }
    }
    if (keyData)
        CFRelease(keyData);
    return ret;
    
}
- (void)configureHTTPHeaderField {
    
    [_manager.requestSerializer setValue:@"ios"         forHTTPHeaderField:@"os"];
    [_manager.requestSerializer setValue:SystemVersion  forHTTPHeaderField:@"osVersion"];
    [_manager.requestSerializer setValue:APP_VERSION    forHTTPHeaderField:@"appVersion"];
    [_manager.requestSerializer setValue:@"1.0.0"       forHTTPHeaderField:@"serviceVersion"];
    [_manager.requestSerializer setValue:[self obtainDeviceID] forHTTPHeaderField:@"uuid"];
     NSLog(@"dfsfs-----  %@   %@ ",UserInfoManage.userInfo.token ,UserInfoManage.userInfo);
    if (UserInfoManage.userInfo.token) {
        [_manager.requestSerializer setValue:UserInfoManage.userInfo.token forHTTPHeaderField:@"token"];
    }
//    NSLog(@"     %@ %@",[self obtainDeviceID],UserInfoManage.userInfo.userId);
//    if (UserInfoManage.userInfo.userId) {
//       [_manager.requestSerializer setValue:UserInfoManage.userInfo.userId forHTTPHeaderField:@"userId"];      //47860
//       [_manager.requestSerializer setValue:UserInfoManage.userInfo.cityId  forHTTPHeaderField:@"cityId"];
//    }
    
}

#pragma mark - 通用请求 && GET请求 && POST请求 && 上传请求 && 下载请求
+ (NSURLSessionDataTask *)dataTaskWithMethodType:(MGHTTPMethodType)methodType
                                             api:(NSString *)api
                                      parameters:(NSDictionary *)parameters
                                         success:(SuccessResponseBlock)success
                                         failure:(FailureResponseBlock)failure
{
//    NSDate *currentDate = [NSDate date];//获取当前时间，日期
//    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//    [dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
//    NSString *dateString = [dateFormatter stringFromDate:currentDate];
//    
//    NSData *d = [SecurityUtil encryptAESData:[NSString stringWithFormat:@"%@%@",@"52504",dateString] app_key:KEY];
//    NSString * ss = [NSString stringWithFormat:@"%@",d];
//    NSString *strUrl = [ss stringByReplacingOccurrencesOfString:@" " withString:@""];
//    NSString *strUrl1 = [strUrl stringByReplacingOccurrencesOfString:@"<" withString:@""];
//    NSString *strUrl2 = [strUrl1 stringByReplacingOccurrencesOfString:@">" withString:@""];
//    NSLog(@"strUrl2 %@ %@",dateString,strUrl2);
//    //sign:strUrl2 timestamp:[NSString stringWithFormat:@"%@",dateString]
//
//    MGRequestService *requestService = [MGRequestService sharedAPI];
//    [requestService.manager.requestSerializer setValue:strUrl2         forHTTPHeaderField:@"sign"];
//    [requestService.manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",dateString]         forHTTPHeaderField:@"timestamp"];
    
    NSURLSessionDataTask *task = nil;
//    ReachabilityStatus status=[GLobalRealReachability currentReachabilityStatus];  // 太灵敏了 先禁掉

//    if (status==RealStatusNotReachable) {
//        
//        NSError *error = [NSError errorWithDomain:api code:36003 userInfo:@{@"NSErrorMessageKey":@"网络不给力"}];
//        
//        handleFailure(failure, error);
//        return task;
//    }
//缓存无效 走网络请求
    
    task = [self goRequestWithMethodType:methodType
                                         api:api
                                  parameters:parameters
                                     success:success
                                     failure:failure];
    
    //-------------------------------- 代码段修改结束 ----------------------------//
    return task;
}

+ (NSURLSessionDataTask *)goRequestWithMethodType:(MGHTTPMethodType)methodType
                                              api:(NSString *)api
                                       parameters:(NSDictionary *)parameters
                                          success:(SuccessResponseBlock)success
                                          failure:(FailureResponseBlock)failure
{
    NSURLSessionDataTask *task = nil;
    switch (methodType) {
        case MGHTTPMethodTypeGET:
            task = [RequestService getRequestWithAPI:api parameters:parameters success:success failure:failure];
            break;
        case MGHTTPMethodTypePOST:
            task = [RequestService postRequestWithAPI:api parameters:parameters success:success failure:failure];
            break;
    }
    return task;
}




- (NSURLSessionDataTask *)getRequestWithAPI:(NSString *)api
                                 parameters:(NSDictionary *)parameters
                                    success:(SuccessResponseBlock)success
                                    failure:(FailureResponseBlock)failure
{
    // 添加Token 或者 用户账号信息
    NSLog(@"发起get请求:%@\n请求参数:%@",api,parameters);
    
    NSURLSessionDataTask *dataTask = [_manager GET:api parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        // get成功处理
        [self requestSuccessOperationWithAPI:api
                                  parameters:parameters
                                    response:responseObject
                                        task:task
                                     success:success
                                     failure:failure];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        // get失败处理
        [self requestFailOperationWithAPI:api
                               parameters:parameters
                                    error:error
                                  success:success
                                  failure:failure];
    }];
    
    static dispatch_once_t oncet;
    dispatch_once(&oncet, ^{
        NSHTTPURLResponse *httpURLResponse = (NSHTTPURLResponse *)dataTask.response;
        
        // 打印返回数据请求头数据
        NSLog(@"httpURLResponse.allHeaderFields = %@",httpURLResponse.allHeaderFields);
        // 没用的话可以去掉
    });
    
    return dataTask;
}

- (NSURLSessionDataTask *)postRequestWithAPI:(NSString *)api
                                  parameters:(NSDictionary *)parameters
                                     success:(SuccessResponseBlock)success
                                     failure:(FailureResponseBlock)failure
{
    
    
    NSURLSessionDataTask *dataTask = [_manager POST:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        // post成功处理
        [self requestSuccessOperationWithAPI:api
                                  parameters:parameters
                                    response:responseObject
                                        task:task
                                     success:success
                                     failure:failure];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        // post失败处理
        [self requestFailOperationWithAPI:api
                               parameters:parameters
                                    error:error
                                  success:success
                                  failure:failure];
        
    }];
    
    static dispatch_once_t oncet;
    dispatch_once(&oncet, ^{
        NSHTTPURLResponse *httpURLResponse = (NSHTTPURLResponse *)dataTask.response;
        // 打印返回数据请求头数据
        NSLog(@"httpURLResponse.allHeaderFields = %@",httpURLResponse.allHeaderFields);
    });
    
    return dataTask;
}


//get,post统一成功处理
-(void)requestSuccessOperationWithAPI:(NSString *)api
                           parameters:(NSDictionary *)parameters
                             response:(id  _Nullable)responseObject
                                 task:(NSURLSessionDataTask * _Nonnull)task
                              success:(SuccessResponseBlock)success
                              failure:(FailureResponseBlock)failure
{
    
    NSInteger code = [[responseObject objectForKey:@"code"] integerValue];
    NSString *msg = [responseObject objectForKey:@"msg"];
    NSLog(@"responseObject = %@ msg=%@",responseObject,msg);
    //>=0成功回调
    
    if (code >= 0) {
        //返回请求成功结果
        handleSuccess(success, responseObject);
        
    } else {
        
        NSError *error = [NSError errorWithDomain:api code:code userInfo:@{@"NSErrorMessageKey":msg?msg:@""}];
        //返回请求失败结果
        handleFailure(failure, error);
        
    }
}

//get,post统一错误处理
- (void)requestFailOperationWithAPI:(NSString *)api
                         parameters:(NSDictionary *)parameters
                              error:(NSError * _Nonnull)error
                            success:(SuccessResponseBlock)success
                            failure:(FailureResponseBlock)failure
{
    //构建联网失败信息
    NSString *errorDescription = [self descriptionForErrorCode:error.code];
    
    NSLog(@"Fail error %ld - %@", (long)error.code, errorDescription);
    
    //响应头错误码获取
    NSString *localizedDescription = [error.userInfo objectForKey:@"NSLocalizedDescription"];
    NSLog(@"requestFail,localizedDescription = %@",localizedDescription);
    /*!
     * 服务器返回码判断 304 是标准缓存协议 执行本地缓存使用逻辑
     */
     NSError *failureError = [NSError errorWithDomain:api code:(long)error.code userInfo:@{@"NSErrorMessageKey":errorDescription?errorDescription:@""}];
     handleFailure(failure, failureError);
    

}
void handleFailure (FailureResponseBlock failure , NSError *error ) {
    
    if (failure)
        failure(error);
    else
        DLog(@"该api没有Fail block");
}
void handleSuccess (SuccessResponseBlock success , id result ) {
    
    if (success)
        success(result);
    else
        DLog(@"该api没有Success block");
}


- (NSString *)descriptionForErrorCode:(NSInteger)code {
    switch (code) {
        case 400: return @"网络错误400";
        case 404: return @"网络错误404";
        case -10001: return @"参数不正确";
        case -10002: return @"没有权限（用户不存在或没有登录）";
        case -10003: return @"数据库错误";
        case NSURLErrorCancelled:   return @"请求取消";
        case NSURLErrorUnknown: return @"未知URL错误";
        case NSURLErrorBadURL: return @"URL异常";
        case NSURLErrorTimedOut: return @"请求超时";
        case NSURLErrorUnsupportedURL: return @"不支持的URL";
        case NSURLErrorCannotFindHost: return @"无法找到主机";
        case NSURLErrorCannotConnectToHost: return @"无法连接到主机";
        case NSURLErrorNetworkConnectionLost: return @"网络连接丢失";
        case NSURLErrorDNSLookupFailed: return @"DNS查找失败";
        case NSURLErrorHTTPTooManyRedirects: return @"HTTP重定向过多";
        case NSURLErrorResourceUnavailable: return @"资源不可使用";
        case NSURLErrorNotConnectedToInternet: return @"因特网无法连接";
        case NSURLErrorRedirectToNonExistentLocation: return @"重定向至不存在的位置";
        case NSURLErrorBadServerResponse: return @"服务器响应异常";
        case NSURLErrorUserCancelledAuthentication: return @"用户取消验证";
        case NSURLErrorUserAuthenticationRequired: return @"需要用户验证";
        case NSURLErrorZeroByteResource: return @"零字节资源";
        case NSURLErrorCannotDecodeRawData: return @"无法解码原数据rawData";
        case NSURLErrorCannotDecodeContentData: return @"无法解码内容数据contentData";
        case NSURLErrorCannotParseResponse: return @"无法解析响应";
        case NSURLErrorFileDoesNotExist: return @"文件不存在";
        case NSURLErrorFileIsDirectory: return @"文件是路径";
        case NSURLErrorNoPermissionsToReadFile: return @"未授权读取文件";
        case NSURLErrorDataLengthExceedsMaximum: return @"数据长度超出最大值";
            
            // SSL errors
        case NSURLErrorSecureConnectionFailed: return @"安全连接失败";
        case NSURLErrorServerCertificateHasBadDate: return @"服务器证书日期异常";
        case NSURLErrorServerCertificateUntrusted: return @"服务器证书不可信";
        case NSURLErrorServerCertificateHasUnknownRoot: return @"服务器证书root未知";
        case NSURLErrorServerCertificateNotYetValid: return @"服务器证书未生效";
        case NSURLErrorClientCertificateRejected: return @"客户证书拒绝";
        case NSURLErrorClientCertificateRequired: return @"需要客户证书";
        case NSURLErrorCannotLoadFromNetwork: return @"无法从网络加载";
            
            // Download and file I/O errors
        case NSURLErrorCannotCreateFile: return @"无法创建文件";
        case NSURLErrorCannotOpenFile: return @"无法打开文件";
        case NSURLErrorCannotCloseFile: return @"无法关闭文件";
        case NSURLErrorCannotWriteToFile: return @"无法写入到文件";
        case NSURLErrorCannotRemoveFile: return @"无法删除文件";
        case NSURLErrorCannotMoveFile: return @"无法移动文件";
        case NSURLErrorDownloadDecodingFailedMidStream: return @"下载解码失败MidStream";
        case NSURLErrorDownloadDecodingFailedToComplete: return @"下载解码失败ToComplete";
            
        case NSURLErrorInternationalRoamingOff: return @"NSURLErrorInternationalRoamingOff";
        case NSURLErrorCallIsActive: return @"NSURLErrorCallIsActive";
        case NSURLErrorDataNotAllowed: return @"NSURLErrorDataNotAllowed";
        case NSURLErrorRequestBodyStreamExhausted: return @"NSURLErrorRequestBodyStreamExhausted";
            
        case -1022: return @"网络安全要求https";                                      // NSURLErrorAppTransportSecurityRequiresSecureConnection  //必须iOS9
        case -995: return @"NSURLErrorBackgroundSessionRequiresSharedContainer";    // NSURLErrorBackgroundSessionRequiresSharedContainer，    // 必须iOS8
        case -996: return @"NSURLErrorBackgroundSessionInUseByAnotherProcess";      // NSURLErrorBackgroundSessionInUseByAnotherProcess        // 必须iOS8
        case -997: return @"NSURLErrorBackgroundSessionWasDisconnected";            // NSURLErrorBackgroundSessionWasDisconnected              // 必须iOS8
            
        default:
            return @"";
    }
}




@end
